package org.maiyoframework.core.jpa;

import java.io.Serializable;
import java.util.List;

import javax.persistence.Query;
import javax.persistence.metamodel.EntityType;
import javax.servlet.http.HttpServletRequest;

import org.maiyoframework.core.common.BeanUtils;
import org.maiyoframework.core.web.page.Page;
import org.maiyoframework.core.web.page.PageResult;
import org.maiyoframework.core.web.page.Pagination;

public class BaseDaoImpl<T extends Serializable> extends DaoSupport<T>
		implements BaseDao<T> {

	public T save(T entity) {
		em.persist(entity);
		return entity;
	}

	public Integer deleteAll(Serializable... ids) {
		for (Serializable id : ids) {
			em.remove(em.getReference(entityClass, id));
		}
		return ids.length;
	}

	public T deleteById(Serializable id) {
		T entity = em.find(entityClass, id);
		if (entity != null) {
			em.remove(entity);
		}
		return entity;
	}
	
	public void delete(T entity){
		em.remove(entity);
	}

	public T saveOrUpdate(T entity) {
		return em.merge(entity);
	}
	
	public T updateDynamic(T entity) {
		EntityType<T> cm = em.getMetamodel().entity(entityClass);
		String id = cm.getId(cm.getIdType().getJavaType()).getName();
		T po = null;
		try {
			po = em.find(entityClass, entity.getClass().getMethod(
									BeanUtils.catchGetMethodByProperty(id)).invoke(entity));
			copyToPersistentObject(entity, cm, po, id);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return po;
	}
	
	public T findById(Serializable id) {
		return em.find(entityClass, id);
	}

	public T findUnique(Finder finder) {
		List<T> entity = findList(finder, 0, 1);
		if (entity != null && entity.size() > 0) {
			return entity.get(0);
		}
		return null;
	}

	public Page<T> findPage(Finder finder, HttpServletRequest req, Integer pageNo,
			Integer pageSize, int pageCount) {
		// 处理页数、开始结束位置等
		Pagination<T> pn = new Pagination<T>(pageNo, pageSize);
		// 获取记录集与总记录数
		PageResult<T> pageResult = this.getPageResult(finder, pn.getStartIndex(), pn.getPageSize());
		// 返回分页对象
		return pn.setPage(pageResult, pn.getPageNo(), req, finder.getUrlParams(), pageCount);
	}

	@SuppressWarnings("unchecked")
	public List<T> findList(Finder finder, int start, int maxSize) {
		String beanName = BeanUtils.getEntityClassName(entityClass);
		Query query = em.createQuery("select bean from " + beanName + " bean"
				+ finder.createWhere() + finder.createOrderBy());
		// Start，pageSize任一为-1,则查询全部
		if (start != -1 && maxSize != -1)
			query.setFirstResult(start).setMaxResults(maxSize);
		finder.setParameters(query);
		return query.getResultList();
	}

	public List<T> findList(Finder finder) {
		return findList(finder, -1, -1);
	}

}
